#ifndef __GlTriangle_h__
#define __GlTriangle_h__

#include <cstring>
#include <iostream>
#include <vector>
#include "GlMain.h"
#include "GlPosition.h"

namespace GraphicLibrary
{
	class GlExport Triangle
	{
		public:
			enum ExceptionList
			{
				ElInvalidTriangle
			};
			typedef std::vector<Triangle>	TriangleArray;
			Position	mVertexes[3];
			inline Triangle()
			{}
			inline Triangle(const Position &a, const Position &b, const Position &c)
			{
				mVertexes[0] = a;
				mVertexes[1] = b;
				mVertexes[2] = c;
			}
			inline Triangle(const Position *vertexes)
			{
				memcpy(mVertexes, vertexes, sizeof(Position) * 3);
			}
			bool contains(const Position &pos) const;
			void getCoordinates(const Position &pos, float &x, float &y, float &z) const;
			inline bool isRealTriangle() const	{return mVertexes[0] != mVertexes[1] && mVertexes[1] != mVertexes[2] && mVertexes[0] != mVertexes[2] && getDown() != 0.0f;}
			inline float getDown() const
			{
				const float &Ax = mVertexes[0].mX;
				const float &Bx = mVertexes[1].mX;
				const float &Cx = mVertexes[2].mX;
				const float &Ay = mVertexes[0].mY;
				const float &By = mVertexes[1].mY;
				const float &Cy = mVertexes[2].mY;
				return (Ax - Cx)*(By - Cy) - (Ay - Cy)*(Bx - Cx);
			}
			inline bool operator == (const Triangle &other) const	{return mVertexes[0] == other.mVertexes[0] && mVertexes[1] == other.mVertexes[1] && mVertexes[2] == other.mVertexes[2];}
			inline bool operator != (const Triangle &other) const	{return !operator == (other);}
	};

	inline std::ostream& operator << (std::ostream &stream, const Triangle &t)
	{
		std::cout << "Triangle(" << t.mVertexes[0] << ", " << t.mVertexes[1] << ", " << t.mVertexes[2] << ")";
		return stream;
	}
}

#endif // __GlTriangle_h__
